package top.guinguo.advance_04.searcher.util;

import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.queryParser.ParseException;
import org.apache.lucene.queryParser.QueryParser;
import org.apache.lucene.search.NumericRangeQuery;
import org.apache.lucene.search.Query;
import org.apache.lucene.util.Version;

import java.text.SimpleDateFormat;
import java.util.regex.Pattern;

/**
 * 对于某些QueryParser（FuzzyQuery，WildCardQuery）在查询时会使得性能降低，所以考虑将这些查询取消。
 * 在具体的查询时，很有可能有这样一种需求：需要获取的是一个数字的范围查询，所以必须扩展原有的QueryParser才能进行查询。
 * 1.限制性能低的查询
 * Created by guin_guo on 2017/1/3.
 */
public class CustomParser extends QueryParser {
    public CustomParser(Version matchVersion, String f, Analyzer a) {
        super(matchVersion, f, a);
    }

    @Override
    protected Query getFuzzyQuery(String field, String termStr, float minSimilarity) throws ParseException {
        throw new ParseException("由于性能原因，已经禁用了模糊查询，请输入更精确的信息进行查询");
    }

    @Override
    protected Query getWildcardQuery(String field, String termStr) throws ParseException {
        throw new ParseException("由于性能原因，已经禁用了通配符查询，请输入更精确的信息进行查询");
    }

    @Override
    protected Query getRangeQuery(String field, String part1, String part2, boolean inclusive) throws ParseException {
        if (field.equals("size")) {
            return NumericRangeQuery.newIntRange(field,
                    Integer.parseInt(part1), Integer.parseInt(part2), inclusive, inclusive);
        } else if (field.equals("date")) {
            String format = null;
            Pattern p = null;
            if (part1.contains("-") && part2.contains("-")) {
                format = "yyyy-MM-dd";
                p = Pattern.compile("\\d{4}-[01]?\\d-\\d{2}");
            } else if (part1.contains("/") && part2.contains("/")) {
                format = "yyyy/MM/dd";
                p = Pattern.compile("\\d{4}/[01]?\\d/\\d{2}");
            } else {
                throw new ParseException("请输入date格式为：yyyy-MM-dd 或者 yyyy/MM/dd 的日期格式");
            }
            if (!(p.matcher(part1).matches() && p.matcher(part2).matches())) {
                throw new ParseException("请输入date格式为：" + format + " 的日期格式");
            } else {
                try {
                    SimpleDateFormat sdf = new SimpleDateFormat(format);
                    long start  = sdf.parse(part1).getTime();
                    long end    = sdf.parse(part2).getTime();
                    return NumericRangeQuery.newLongRange(field, start, end, inclusive, inclusive);
                } catch (java.text.ParseException e) {
                    e.printStackTrace();
                }
            }

        }
        return super.getRangeQuery(field, part1, part2, inclusive);
    }
}
